﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [Header("Movement")]
    public float moveSpeed = 2f;
    public Vector3 MoveVelocity { get; private set; }

    [Header("Hand Check")]
    public Transform hand;
    public float handCheckRadius;
    private readonly Collider2D[] _handCheckResult = new Collider2D[10];
    private SolutionObject _holdSolutionObject; // 手持的物品

    [Header("Stun")]
    [SerializeField]
    private float stunDuration;

    private Rigidbody2D _rigidbody2D;

    public bool IsInteracting { get; private set; }

    public bool IsStuning { get; private set; }

    public bool IsHolding => _holdSolutionObject != null;

    private float stunTimer;

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawSphere(transform.position, handCheckRadius);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Stun") && !IsStuning)
        {
            AudioManager.Instance.PlaySound("Stun");
            IsStuning = true;
        }
    }

    private void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        if (IsStuning)
        {
            stunTimer += Time.deltaTime;
            if(stunTimer > stunDuration)
            {
                stunTimer = 0;
                IsStuning = false;
            }
        }
        if (IsInteracting || IsStuning)
        {
            MoveVelocity = Vector3.zero;
            return;
        }

        UpdateMovement();
        UpdateFlip();
        UpdateHandle();
    }

    private void FixedUpdate()
    {
        _rigidbody2D.velocity = MoveVelocity;
    }


    private void UpdateMovement()
    {
        var h = Input.GetAxisRaw("Horizontal");
        var v = Input.GetAxisRaw("Vertical");

        var moveDirection = new Vector3(h, v, 0f);
        moveDirection.Normalize();

        MoveVelocity = moveDirection * moveSpeed;
    }

    public void UpdateFlip()
    {
        var scale = transform.localScale;
        if (MoveVelocity.x > 0f)
        {
            scale.x = -Mathf.Abs(scale.x);
        }
        else if (MoveVelocity.x < 0f)
        {
            scale.x = Mathf.Abs(scale.x);
        }

        transform.localScale = scale;
    }

    private void UpdateHandle()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var count = Physics2D.OverlapCircleNonAlloc(hand.position, handCheckRadius, _handCheckResult);
            for (int i = 0; i < count; i++)
            {
                if (_handCheckResult[i].CompareTag("Machine"))
                {
                    // 与机器交互
                    var machine = _handCheckResult[i].GetComponent<Machine>();
                    if (machine != null && BuySolutionObject(machine)) return;
                }
                else if (_handCheckResult[i].CompareTag("ITGuy"))
                {
                    // 与程序员交互
                    var itGuy = _handCheckResult[i].GetComponent<ITGuy>();
                    if (itGuy != null && GiveSolutionObject(itGuy)) return;
                }
            }
        }
        //throw holding object
        else if (Input.GetKeyDown(KeyCode.T) && IsHolding)
        {
            AudioManager.Instance.PlaySound("Drop");
            Destroy(_holdSolutionObject.gameObject);
            _holdSolutionObject = null;
        }
    }

    private bool BuySolutionObject(Machine machine)
    {
        if (IsHolding) return false;
        if (machine.InUse) return false;

        IsInteracting = true;
        machine.BuySolutionObject(HoldObject);
        return true;
    }

    private void HoldObject(SolutionObject solutionObject)
    {
        IsInteracting = false;

        // 抓住道具
        _holdSolutionObject = solutionObject;
        solutionObject.transform.SetParent(hand);
        solutionObject.transform.localPosition = Vector3.zero;
    }

    private bool GiveSolutionObject(ITGuy itGuy)
    {
        if (!IsHolding) return false;

        DropObject(itGuy);
        return true;
    }

    private void DropObject(ITGuy itGuy)
    {
        itGuy.OnProblemSolved(_holdSolutionObject.problemSolved);
        Destroy(_holdSolutionObject.gameObject);
        _holdSolutionObject = null;
    }
}